package com.unknown.explorer;

import javax.vecmath.GMatrix;
import javax.vecmath.GVector;
import javax.vecmath.Matrix3d;
import javax.vecmath.Matrix3f;

import org.ejml.simple.SimpleMatrix;

import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;

public class puzzlePiece {
	private int x,y,z;
	public Object3D obj3D;
	public int blockIntervalSize = 20;
	public int offset = -70; 
	public String name;
	private GVector localCoordinates = new GVector(3);
	
	private int prevX, prevY, prevZ;
	private int prevLocalX, prevLocalY, prevLocalZ;
	
	public boolean calculatePosition()
	{
		if(obj3D == null)
		{
			return false;
		}
		obj3D.clearTranslation();
		obj3D.translate(x*blockIntervalSize + offset, y*blockIntervalSize + offset, z*blockIntervalSize);
		return true;
	}
	public float getObject3DXPos()
	{
		SimpleVector g = obj3D.getTranslation();
		return g.x;
	}
	public float getObject3DYPos()
	{
		SimpleVector g = obj3D.getTranslation();
		return g.y;
	}
	public void moveX(int val)
	{
		this.prevX = this.x;
		this.x += val;
	}
	public void moveY(int val)
	{
		this.prevY = this.y;
		this.y += val;
	}
	public void moveZ(int val)
	{
		this.prevZ = this.z;
		this.z += val;
	}
	public int getX()
	{
		return this.x;
	}
	public int getY()
	{
		return this.y;
	}
	public int getZ()
	{
		return this.z;
	}
	public void setInitializePosition(int x, int y, int z)
	{
		this.x = x;
		this.y = y;
		this.z = z;
		this.prevX = x;
		this.prevY = y;
		this.prevZ = z;
	}
	public void setX(int val)
	{
		this.prevX = this.x;
		this.x = val;
	}
	public void setY(int val)
	{
		this.prevY = this.y;
		this.y = val;
	}
	public void setZ(int val)
	{
		this.prevZ = this.z;
		this.z = val;
	}
	public void setInitializeLocalPosition(int x, int y, int z)
	{
		this.prevLocalX = x;
		this.prevLocalY = y;
		this.prevLocalZ = z;
		
		double[] vector = new double[3];
		vector[0] = x;
		vector[1] = y;
		vector[2] = z;
		this.localCoordinates.set(vector);
	}
	public void setLocalCoordinates(int x, int y, int z)
	{	
		this.prevLocalX = (int) this.localCoordinates.getElement(0);
		this.prevLocalY = (int) this.localCoordinates.getElement(1);
		this.prevLocalZ = (int) this.localCoordinates.getElement(2);
		
		double[] vector = new double[3];
		vector[0] = x;
		vector[1] = y;
		vector[2] = z;
		this.localCoordinates.set(vector);
	}
	public int getLocalX()
	{
		return (int) this.localCoordinates.getElement(0);
	}
	public int getLocalY()
	{
		return (int) this.localCoordinates.getElement(1);
	}
	public int getLocalZ()
	{
		return (int) this.localCoordinates.getElement(2);
	}
	public void transformCoordinates(Matrix3d m)
	{
		//save previous local coordinates
		this.prevLocalX = this.getLocalX();
		this.prevLocalY = this.getLocalY();
		this.prevLocalZ = this.getLocalZ();
		
		this.prevX = this.getX();
		this.prevY = this.getY();
		this.prevZ = this.getZ();
		
		GMatrix rotGM = new GMatrix(3, 3);
		rotGM.set(m);
		
		SimpleVector sv = new SimpleVector(this.getLocalX(), this.getLocalY(), this.getLocalZ());
		
		double[] doubArray = new double[3];
		doubArray[0] = this.getLocalX();
		doubArray[1] = this.getLocalY();
		doubArray[2] = this.getLocalZ();
		
		GVector svb = new GVector(doubArray);
		
		GVector result = new GVector(3);
		result.mul(svb,rotGM);
		
		Logger.log("before posistion for " + this.name + ": " + this.localCoordinates.getElement(0) + ", " + this.localCoordinates.getElement(1) + ", " + this.localCoordinates.getElement(2));
		Logger.log("after position for " + this.name + ": " + result.getElement(0) + ", " + result.getElement(1) + ", " + result.getElement(2));
		
		SimpleVector svResult = new SimpleVector(result.getElement(0), result.getElement(1), result.getElement(2));
		
		svResult.sub(sv);
		
		this.moveX((int) Math.round(svResult.x));
		this.moveY((int) Math.round(svResult.y));
		this.moveZ((int) Math.round(svResult.z));
		
		double[] moveLocal = new double[3];
		moveLocal[0] = Math.round(svResult.x);
		moveLocal[1] = Math.round(svResult.y);
		moveLocal[2] = Math.round(svResult.z);
		GVector jj = new GVector(moveLocal);
		this.localCoordinates.add(jj);
		
//		//do the transform and save new local coordinates
//		GMatrix mm = new GMatrix(3, 3);
//		mm.set(m);
//		GVector vv = new GVector(3);
//		vv.mul(this.localCoordinates, mm);
//		this.localCoordinates = vv;
//		
//		//update non-local x,y,z coordinates after transform
//		this.moveX((int)(this.localCoordinates.getElement(0) - prevLocalX));
//		this.moveY((int)(this.localCoordinates.getElement(1) - prevLocalY));
//		this.moveZ((int)(this.localCoordinates.getElement(2) - prevLocalZ));
	}
	public void revertPreviousPosition()
	{
		double[] dd = new double[3];
		dd[0] = this.prevLocalX;
		dd[1] = this.prevLocalY;
		dd[2] = this.prevLocalZ;
		
		this.localCoordinates.set(dd);
		
		this.x = this.prevX;
		this.y = this.prevY;
		this.z = this.prevZ;
	}
}
